package com.societyGames.flashForms
{
import com.societyGames.system.EventObject;

import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Rectangle;

public class Splitter extends Sprite
{
  private var _displayObject:DisplayObject;
  private var _bounds:Rectangle;
  private var _cursor:DisplayObject;
  private var _draggedEventObject:EventObject;
  private var _droppedEventObject:EventObject;
  private var _desiredWidth:Number;
  private var _desiredHeight:Number;

  public function Splitter(displayObject:DisplayObject, cursor:DisplayObject)
  {
    this.addEventListener(MouseEvent.ROLL_OVER, splitterRollOverHandler);
    this.addEventListener(MouseEvent.ROLL_OUT, splitterRollOutHandler);
    this.addEventListener(MouseEvent.MOUSE_DOWN, splitterDownHandler);

    this._draggedEventObject = new EventObject(this, "DRAGGED", Event);
    this._droppedEventObject = new EventObject(this, "DROPPED", Event);
    this._displayObject = displayObject;
    this.addChild(this._displayObject);
    this._cursor = cursor;
  }

  public function set bounds(value:Rectangle):void
  {
    this._bounds = value;
  }

  public function get bounds():Rectangle
  {
    return this._bounds;
  }

  public override function set width(value:Number):void
  {
    this._desiredWidth = value;
    this._displayObject.width = value;
  }

  public override function set height(value:Number):void
  {
    this._desiredHeight = value;
    this._displayObject.height = value;
  }

  public function get draggedEventObject():EventObject
  {
    return this._draggedEventObject;
  }

  public function get droppedEventObject():EventObject
  {
    return this._droppedEventObject;
  }

  private function splitterRollOverHandler(event:MouseEvent):void
  {
    MouseCursor.instance.lockCursor(this._cursor, this, -this._cursor.width / 2, -this._cursor.height / 2);
  }

  private function splitterRollOutHandler(event:MouseEvent):void
  {
    MouseCursor.instance.unlockCursor(this);
  }

  private function splitterDownHandler(event:MouseEvent):void
  {
    //Stop listening to normal events and enter the down state.
    removeEventListener(MouseEvent.ROLL_OVER, splitterRollOverHandler);
    removeEventListener(MouseEvent.ROLL_OUT, splitterRollOutHandler);
    removeEventListener(MouseEvent.MOUSE_DOWN, splitterDownHandler);
    this.stage.addEventListener(MouseEvent.MOUSE_UP, splitterUpHandler);
    this.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);

    //Start the actual drag.
    this.startDrag(false, this._bounds);
  }

  private function splitterUpHandler(event:MouseEvent):void
  {
    //Restore all the normal listeners
    addEventListener(MouseEvent.ROLL_OVER, splitterRollOverHandler);
    addEventListener(MouseEvent.ROLL_OUT, splitterRollOutHandler);
    addEventListener(MouseEvent.MOUSE_DOWN, splitterDownHandler);
    this.stage.removeEventListener(MouseEvent.MOUSE_UP, splitterUpHandler);
    this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);

    //If the cursor somehow migrated off of the splitter, unlock it.
    if (!this._displayObject.hitTestPoint(event.stageX, event.stageY, true))
    {
      MouseCursor.instance.unlockCursor(this);
    }

    //Stop the drag.
    this.stopDrag();

    //Raise event
    this._droppedEventObject.dispatchEvent();
  }

  private function mouseMoveHandler(event:MouseEvent):void
  {
    this._draggedEventObject.dispatchEvent();
  }
}
}